package com.nationart.backend.shiro;

import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import com.nationart.backend.entity.SysUser;
import com.nationart.backend.service.ShiroService;
import com.nationart.backend.service.SysUserService;


public class ShiroRealm extends AuthorizingRealm {
	private Logger logger = LoggerFactory.getLogger(ShiroRealm.class);
	@Autowired
    private SysUserService userInfoService;
	
	@Autowired
	private ShiroService shiroService;
	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// TODO Auto-generated method stub
		logger.debug("doGetAuthorizationInfo");
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		SysUser userInfo = (SysUser) principals.getPrimaryPrincipal();
		Set<String> pers = shiroService.getUserPermissions(userInfo.getUserId());
		authorizationInfo.addStringPermissions(pers);
        return authorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// TODO Auto-generated method stub
		logger.debug("doGetAuthenticationInfo");
			if(token instanceof OAuthToken) {
				//已经登录过
				Session object = (Session)redisTemplate.opsForValue().get(token);
				if(object == null) {
					throw new IncorrectCredentialsException("token失效，请重新登录");
				}
				SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(object.getAttribute("activeUser"), token.getPrincipal(), getName());
				return info;
			}else {
				//走的登录逻辑
				//获取用户的输入的账号.
				String username = (String)token.getPrincipal();
//		        System.out.println(token.getCredentials());
		        //通过username从数据库中查找 User对象，如果找到，没找到.
		        //实际项目中，这里可以根据实际情况做缓存，如果不做，Shiro自己也是有时间间隔机制，2分钟内不会重复执行该方法
		        SysUser userInfo = userInfoService.queryByUserName(username);
		        if (userInfo == null) {
		            throw new UnknownAccountException("用户不存在");
		        }else {
		        	
		        }
		        if (userInfo.getStatus() == 0) { //账户冻结
		            throw new LockedAccountException();
		        }
	  	        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
		                userInfo, 
	 	                userInfo.getPassword(), //密码
	    	                ByteSource.Util.bytes(userInfo.getSalt()),//salt=username+salt
	 	                getName()  //realm name
		        );
		        
	  	        return authenticationInfo;
			}
	        
	}

}
